package top.v5it.japi.plus.common.func;

import java.util.Objects;

/**
 * 自定义函数，4个输入，1个输出
 *
 * @author zhanpu
 * @date 2021/8/25
 */
@FunctionalInterface
public interface Func4<T, U, X, Y, R, E extends Throwable> {

    /**
     * 此函数接收4个输入，1个输出
     *
     * @param t 输入参数1
     * @param u 输入参数2
     * @param x 输入参数3
     * @param y 输入参数4
     * @return 返回值
     * @throws E 调用函数可能输出异常
     */
    R apply(T t, U u, X x, Y y) throws E;


    /**
     * 先调用本函数，再基于本函数结果调用输入函数
     *
     * @param after 输入函数
     * @param <V>   输出类型
     * @return 返回V
     */
    default <V> Func4<T, U, X, Y, V, E> andThen(Func1<? super R, ? extends V, ? extends E> after) {
        Objects.requireNonNull(after);

        return (t, u, x, y) -> {
            try {
                return after.apply(apply(t, u, x, y));
            } catch (Throwable e) {
                throw new FuncException(e);
            }
        };
    }

    /**
     * 基于本函数返回{@link FuncException}
     *
     * @param t 参数t
     * @param u 参数u
     * @param x 参数x
     * @param y 参数y
     * @return R 返回值
     */
    default R applyWithFuncException(T t, U u, X x, Y y) {
        try {
            return apply(t, u, x, y);
        } catch (Throwable e) {
            throw new FuncException(e);
        }
    }
}
